package com.crx.springbootinit.service.impl;

import cn.hutool.core.lang.hash.Hash;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crx.springbootinit.mapper.UserMapper;
import com.crx.springbootinit.model.dto.page.PageVO;
import com.crx.springbootinit.model.dto.user.UserEnableDTO;
import com.crx.springbootinit.model.dto.user.UserPageDTO;
import com.crx.springbootinit.model.dto.user.UserUpdateMyRequest;
import com.crx.springbootinit.model.entity.Collect;
import com.crx.springbootinit.model.entity.Love;
import com.crx.springbootinit.model.entity.User;
import com.crx.springbootinit.model.vo.post.PostHomeVO;
import com.crx.springbootinit.model.vo.user.UserAndPostInfo;
import com.crx.springbootinit.model.vo.user.UserPageVO;
import com.crx.springbootinit.service.*;
import com.crx.springbootinit.utils.AuthUtils;
import com.crx.springbootinit.utils.ConstellationUtils;
import com.crx.springbootinit.utils.ThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDate;
import java.time.Period;
import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-10-21
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IFollowService followService;

    @Autowired
    private ILoveService loveService;

    @Autowired
    private ICollectService collectService;

    @Autowired
    private IPostService postService;

    public UserServiceImpl(@Lazy IFollowService followService){
        this.followService = followService;
    }

    @Override
    public User getLoginUser(Long userId) {
        User user = baseMapper.selectById(userId);
        return user;
    }

    @Override
    public PageVO<UserPageVO> queryUserPage(UserPageDTO userPageDTO) {
        Integer pageNo = userPageDTO.getPageNo();
        Integer pageSize = userPageDTO.getPageSize();
        String account = userPageDTO.getAccount();
        String nickname = userPageDTO.getNickname();
        Integer role = userPageDTO.getRole();
        Integer roleStatus = userPageDTO.getRoleStatus();
        Page<User> page = new Page<>(pageNo, pageSize);
        Page<User> p = lambdaQuery()
                .like(StringUtils.isNotBlank(account), User::getAccount, account)
                .like(StringUtils.isNotBlank(nickname), User::getNickname, nickname)
                .eq(role != null, User::getRole, role)
                .eq(roleStatus != null, User::getRoleStatus, roleStatus)
                .page(page);
        return PageVO.of(p, UserPageVO.class);
    }

    @Override
    public void enableUser(UserEnableDTO userEnableDTO) {
        lambdaUpdate()
                .eq(User::getId,userEnableDTO.getId())
                .set(User::getRoleStatus, userEnableDTO.getRoleStatus())
                .update();
    }

    @Override
    public UserAndPostInfo getUserAndPostInfo(Long userId,int pageNum, int pageSize) {
        UserAndPostInfo userAndPostInfo = new UserAndPostInfo();
        User user = baseMapper.selectById(userId);
        BeanUtils.copyProperties(user,userAndPostInfo);
        int years = Period.between(user.getBirthDate(), LocalDate.now()).getYears();
        userAndPostInfo.setAge(years);
        String constellation = ConstellationUtils.getConstellation(user.getBirthDate().getMonthValue(), user.getBirthDate().getDayOfMonth());
        userAndPostInfo.setConstellation(constellation);
        Long postCount = postService.getPostCount(userId);
        Long loveAndCollectContByUserId = loveService.getLoveAndCollectContByUserId(userId);
        Long followCountByUserId = followService.getFollowCountByUserId(userId);
        Long fansCountByUserId = followService.getFansCountByUserId(userId);
        userAndPostInfo.setPostCount(postCount);
        userAndPostInfo.setFansCount(fansCountByUserId);
        userAndPostInfo.setFollowCount(followCountByUserId);
        userAndPostInfo.setLoveCollectCount(loveAndCollectContByUserId);
        PageVO<PostHomeVO> myPost = postService.getMyPost(userId, pageNum, pageSize,1);
        userAndPostInfo.setPostHomeList(myPost);
        return userAndPostInfo;
    }

    /**
     * 注册账户
     * @param acount
     * @param password
     */
    @Override
    public void register(String acount, String password) {
        User user = new User();
        String randomString = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        user.setNickname("用户" + randomString);
        user.setAddress("桂林");
        user.setAvatar("https://tse4-mm.cn.bing.net/th/id/OIP-C.jHUH4s7TQ48X_B-1iozuJgHaHa?rs=1&pid=ImgDetMain");
        user.setGender("未知");
        user.setBirthDate(LocalDate.now());
        user.setAccount(acount);
        user.setPassword(password);
        user.setRole(2);
        user.setRoleStatus(1);
        user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        save(user);
    }

    @Override
    public PageVO<PostHomeVO> getMyPost(Long userId,int pageNum, int pageSize,int type) {
        PageVO<PostHomeVO> myPost = postService.getMyPost(userId, pageNum, pageSize,type);
        return myPost;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editPrivateMessage(UserUpdateMyRequest userUpdateMyRequest) {
        Long userId = ThreadLocalUtil.get("userId");
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId,userId);
        updateWrapper.set(!StringUtils.isBlank(userUpdateMyRequest.getName()),User::getNickname,userUpdateMyRequest.getName());
        updateWrapper.set(!StringUtils.isBlank(userUpdateMyRequest.getUserAvatar()),User::getAvatar,userUpdateMyRequest.getUserAvatar());
        updateWrapper.set(!StringUtils.isBlank(userUpdateMyRequest.getBio()),User::getBio,userUpdateMyRequest.getBio());
        updateWrapper.set(!StringUtils.isBlank(userUpdateMyRequest.getGender()),User::getGender,userUpdateMyRequest.getGender());
        // 如果前端传递的是字符串，需要转换成 LocalDate
        String userBirthdayStr = userUpdateMyRequest.getBirthday();
        if (!StringUtils.isBlank(userBirthdayStr)) {
            updateWrapper.set(!StringUtils.isBlank(userUpdateMyRequest.getBirthday()),User::getBirthDate,LocalDate.parse(userBirthdayStr));
        }
        if(!StringUtils.isBlank(userUpdateMyRequest.getName())) {
            loveService.update(new LambdaUpdateWrapper<Love>()
                    .eq(Love::getUserId, userId)
                    .set(Love::getNickname, userUpdateMyRequest.getName()));
            collectService.update(new LambdaUpdateWrapper<Collect>()
                    .eq(Collect::getUserId, userId)
                    .set(Collect::getNickname, userUpdateMyRequest.getName()));
        }
        update(updateWrapper);
    }

    @Override
    public int getTotalUserCount() {
        return 0;
    }

    @Override
    public List<HashMap<String, Object>> getUserTrend() {
        return baseMapper.getUserTrend();
    }

    @Override
    public List<HashMap<String, Object>> getUserAgeGroup() {
        return baseMapper.getUserAgeGroup();
    }
}
